package com.itheima.mall.service.ums;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.DigestUtil;
import cn.hutool.crypto.digest.MD5;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itheima.mall.api.ums.*;
import com.itheima.mall.autoconfig.template.OssTemplate;
import com.itheima.mall.exception.BusinessException;
import com.itheima.mall.exception.ExceptionAdvice;
import com.itheima.mall.interceptor.AdminHolder;
import com.itheima.mall.pojo.ums.Admin;
import com.itheima.mall.pojo.ums.UmsAdminRoleRelation;
import com.itheima.mall.pojo.ums.UmsMenu;
import com.itheima.mall.pojo.ums.UmsRole;
import com.itheima.mall.utils.JwtUtils;
import com.itheima.mall.vo.AdminInfoVo;
import com.itheima.mall.vo.PageResult;
import com.itheima.mall.vo.R;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.checkerframework.checker.units.qual.A;
import org.joda.time.LocalDateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;

import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.util.*;

@Service
@Slf4j
public class AdminService {
    @DubboReference
    private AdminServiceApi adminServiceApi;
    @Autowired
    private OssTemplate ossTemplate;
    @DubboReference
    private UmsAdminRoleRelationServiceApi umsAdminRoleRelationServiceApi;
    @DubboReference
    private UmsRoleServiceApi umsRoleServiceApi;
    @DubboReference
    private UmsMenuServiceApi umsMenuServiceApi;
    @DubboReference
    private UmsRoleMenuRelationServiceApi umsRoleMenuRelationServiceApi;
    /**
     * 用户登录并返回token
     * @param map
     * @return
     */
    public Map login(Map map) {
        //获取用户名和密码
        String username = (String) map.get("username");
        String password = (String) map.get("password");
        //根据用户名查找用户信息
        Admin admin = adminServiceApi.findByName(username);
        if(admin == null){
            throw new BusinessException("登录失败");
        }
        if(!StrUtil.equals(password,admin.getPassword())){
            throw new BusinessException("用户名或密码错误");
        }
        if(admin.getStatus() == 0){
            throw new BusinessException("用户已被冻结");
        }
        //更新用户的登录时间
        admin.setLoginTime(DateUtil.date());
        adminServiceApi.update(admin);
        //封装返回的token
        Map<String,Object> claims = new HashMap<>();
        claims.put("username",username);
        claims.put("id",admin.getId());
        //构造token
        String token = JwtUtils.getToken(claims);
        Map res = new HashMap<>();
        res.put("tokenHead","Bearer ");
        res.put("token",token);
        return res;
    }

    /**
     * 登出
     */
    public void logout() {
        AdminHolder.remove();
    }


    /**
     * 返回当前用户信息
     * @return
     */
    public AdminInfoVo info() {
        //获取当前用户的id
        Long adminId = AdminHolder.getUserId();
        AdminInfoVo adminInfoVo = new AdminInfoVo();
        Admin admin = adminServiceApi.info(AdminHolder.getUserId());
        //根据用户id查询其角色
        List<UmsAdminRoleRelation> adminRoleRelationList = umsAdminRoleRelationServiceApi.getUserRole(adminId);
        List<Long> roleIds = CollUtil.getFieldValues(adminRoleRelationList,"roleId",Long.class);
        List<UmsRole> roleList = new ArrayList<>();
        //根据roleId查找角色
        List<UmsMenu> list = new ArrayList<>();
        for (Long roleId : roleIds) {
            R r = umsRoleMenuRelationServiceApi.UmsRoleListMenu(roleId);
            UmsRole userRole = umsRoleServiceApi.getUserRole(roleId);
            roleList.add(userRole);
            List<UmsMenu> data = (List<UmsMenu>) r.getData();
            for (UmsMenu datum : data) {
                list.add(datum);
            }
        }
        List<String> roles = CollUtil.getFieldValues(roleList,"name",String.class);
        adminInfoVo.setMenus(list);
        adminInfoVo.setIcon(admin.getIcon());
        adminInfoVo.setRoles(roles);
        adminInfoVo.setUsername(admin.getUsername());
        return adminInfoVo;
    }

    /**
     * 删除用户信息
     * @param id
     */
    public void delAdmin(Long id) {
        Long adminId = AdminHolder.getUserId();
        //判断删除的是不是当前用户
        if(adminId == id){
            throw new BusinessException("当前用户正在登录,不能删除");
        }
        adminServiceApi.delAdmin(id);
    }

    /**
     * 根据用户名或姓名分页获取用户列表
     * @param keyword
     * @param pageNum
     * @param pageSize
     * @return
     */
    public PageResult list(String keyword, Integer pageNum, Integer pageSize) {
        log.error("keyword:{}",keyword);
        Page adminList = adminServiceApi.list(keyword,pageNum,pageSize);
        PageResult pageResult = new PageResult<>();
        pageResult.setList(adminList.getRecords());
        pageResult.setPageNum(Convert.toInt(adminList.getSize()));
        pageResult.setTotal(Convert.toInt(adminList.getTotal()));
        pageResult.setTotalPage(Convert.toInt(adminList.getPages()));
        return pageResult;
    }

    /**
     * 注册
     * @param admin
     * @return
     */
    public Admin register(Admin admin) {
        admin.setCreateTime(DateUtil.date());
        admin.setLoginTime(DateUtil.date());
        //admin.setIcon();
        admin.setStatus(1);
        adminServiceApi.register(admin);
        return admin;
    }

    /**
     * 涉及ums_admin_role_relation和ums_role
     * 给用户分配角色
     * @param roleIds
     * @param adminId
     */
    public void roleUpdate(Long[] roleIds,Long adminId) {
        adminServiceApi.roleUpdate(adminId,roleIds);
    }

    /**
     * 涉及ums_admin_role_relation,ums_role和ums_admin
     * @param id
     * @return
     */
    public List<UmsRole> getUserRole(Long id) {
        //根据adminId,查询其角色,获取角色id
        List<UmsAdminRoleRelation> umsAdminRoleRelationList = umsAdminRoleRelationServiceApi.getUserRole(id);
        List<Long> roleIds = CollUtil.getFieldValues(umsAdminRoleRelationList, "roleId", Long.class);
        //根据角色id查找其角色详情
        List<UmsRole> umsRoleList = new ArrayList<>();
        for (Long roleId : roleIds) {
            UmsRole umsRole = umsRoleServiceApi.getUserRole(roleId);
            umsRoleList.add(umsRole);
        }
        return umsRoleList;
    }

    /**
     * 根据id查询指定用户信息
     * @param id
     * @return
     */
    public Admin getUserInfoById(Long id) {
        Admin admin = adminServiceApi.getUserInfoById(id);
        return admin;
    }

    /**
     * 根据id更新用户信息
     * @param admin
     * @return
     */
    public void updateUserInfoById(Admin admin) {
        adminServiceApi.updateUserInfoById(admin);
    }

    /**
     * 修改指定用户密码
     * @param map
     * @return
     */
    public void updatePassword(Map map) {
        String newPassword = (String) map.get("newPassword");
        String oldPassword = (String) map.get("oldPassword");
        String username = (String) map.get("username");
        Admin admin = adminServiceApi.findByName(username);
        if(admin == null){
            throw new BusinessException("修改失败");
        }
        if(!StrUtil.equals(oldPassword,admin.getPassword())){
            throw new BusinessException("旧密码输入错误");
        }
        admin.setPassword(newPassword);
        adminServiceApi.update(admin);
    }

    /**
     * 修改用户状态
     * @param id
     * @param status
     * @return
     */
    public void updateStatus(Long id, Integer status) {
        Admin admin = adminServiceApi.getUserInfoById(id);
        admin.setStatus(status);
        adminServiceApi.update(admin);
    }
}
